100 REM ************************************************************
110 REM
120 REM FILENAME     DRAWPCX.BAS
130 REM WRITTEN BY   GARY PEEK
140 REM LAST UPDATE  change in help screen!
150 REM
160 REM DESCRIPTION  DRAW ON VGA SCREEN AND SAVE AS .PCX FILE
170 REM ************************************************************
180 KEY OFF:FOR A=1 TO 10:KEY A,"":NEXT A:CLS
190 FILE$="TEMP":EXT$=".PCX"
200 XMAX=511:YMAX=415:XBMAX=63
210 LRX=XMAX:LRY=YMAX
220 DIM IMAGE%(XBMAX,YMAX)
230 FOR Y%=0 TO YMAX:FOR XB%=0 TO XBMAX:IMAGE%(XB%,Y%)=255:NEXT XB%:NEXT Y%
240 GRID=-1:LMODE=0:CMODE=0
250 REM -----
300 BPL=(LRX+1)/8:REM BYTES PER LINE, VGA12=80=WHOLE SCREEN
310 REM -----
320 GOSUB 65250:REM LOAD ASSEMBLY LANGUAGE SUBROUTINE
330 GOSUB 62000:REM GET VIDEO MONITOR TYPE
340 IF MONITOR$="VGA" THEN SCREEN 12:CLS:GOTO 400
350 BEEP:CLS:PRINT "THIS PROGRAM REQUIRES A VGA MONITOR"
360 IN$=INKEY$:IF IN$="" THEN 360 ELSE END
370 REM -----
400 GOSUB 63000:REM MOUSE RESET AND STATUS
410 IF STATUS=-1 THEN 450
420 BEEP:CLS:PRINT "MOUSE DRIVER NOT INSTALLED OR MOUSE NOT FOUND"
430 IN$=INKEY$:IF IN$="" THEN 430 ELSE END
440 REM -----
450 GOSUB 63800:REM SET MOUSE GRAPHICS CURSOR
460 TOPLIMIT=0:BOTTOMLIMIT=LRY:LEFTLIMIT=0:RIGHTLIMIT=LRX
470 GOSUB 63700:REM SET MOUSE CURSOR LIM.
480 X=256:Y=208:GOSUB 63400:REM SET MOUSE CURSOR POSITION
490 XSENS=30:YSENS=30:THRESHOLD=50:GOSUB 64600:REM SET MOUSE SENSITIVITY
500 REM -----
550 WHITE=15:BLUE=1:YELLOW=14:RED=12:CYAN=3:GREEN=2
560 LWIDTH$="1":LWID=0
570 XOFF=0:YOFF=0:AFUN=0
580 AULX=528:AULY=76:ALRX=630:ALRY=114
590 REM ----- PRINT MESSAGES
650 CLS
660 LOCATE 2,68:PRINT "Filename:  ";
665 LOCATE 3,68:PRINT "<"+FILE$+">"+SPACE$(10-LEN(FILE$));
667 REM
670 LOCATE 6,68:PRINT "Arrow keys=";
680 LOCATE 7,68:PRINT "move X,Y   ";
690 LOCATE 9,68:PRINT "Keys:      ";
700 LOCATE 10,68:PRINT "A=Arrow key";
710 LOCATE 11,68:PRINT "  function ";
720 LINE(AULX,AULY)-(ALRX,ALRY),YELLOW,B
730 LOCATE 13,68:PRINT "D=draw pix ";
740 LOCATE 14,68:PRINT "E=erase pix";
750 LOCATE 15,68:PRINT "SPACE=stop ";
760 LOCATE 16,68:PRINT "W=width    ";
770 LOCATE 17,68:PRINT "C=circle   ";
780 LOCATE 18,68:PRINT "L=line     ";
785 REM
790 LOCATE 20,68:PRINT "F1=redraw";
795 LINE(613,305)-(623,315),CYAN,B:LINE(616,308)-(618,310),WHITE,BF:LINE(618,310)-(620,312),WHITE,BF
800 LOCATE 21,68:PRINT "F2=save  ";
805 LINE(613,321)-(623,331),CYAN,B:LINE(616,324)-(618,326),WHITE,BF:LINE(618,326)-(620,328),WHITE,BF
810 LOCATE 22,68:PRINT "F3=read PCX";
820 LOCATE 23,68:PRINT "F4=writePCX";
830 LOCATE 24,68:PRINT "F5=memory";:LINE(618,376)-(619,377),WHITE,B
840 LOCATE 25,68:PRINT "F6=recall";:LINE(618,391)-(619,392),WHITE,B
850 LOCATE 26,68:PRINT "F7=fill   ";CHR$(254);
860 LOCATE 27,68:PRINT "F8=erase";:LINE(617,420)-(621,426),WHITE,B
870 LOCATE 28,68:PRINT "F9=grid    ";
875 LINE(613,433)-(623,443),CYAN,B:LINE(618,433)-(618,443),CYAN:LINE(613,438)-(623,438),CYAN
880 LOCATE 29,68:PRINT "F10=help  ?";
885 REM -----
890 GOSUB 2400:REM DRAW GRID PER LRX, LRY
895 LOCATE 29,2:PRINT "width=";LWIDTH$;" ";
900 GOSUB 63100:REM MOUSE SHOW CURSOR
990 REM ---------------------------------------------------------------------
995 REM ----- MAIN LOOP
1000 OLDX=X:OLDY=Y
1010 DELAY=.01:GOSUB 63300:REM GET CURSOR POSITION AND BUTTONS
1020 REM ----- CHECK KEYBOARD
1030 IN$=INKEY$:IF IN$="" THEN 1800
1040 REM ----- MOVE X,Y
1050 IF IN$=CHR$(0)+CHR$(75) AND AFUN=0 THEN X=X-1:GOSUB 63400:REM LEFT
1060 IF IN$=CHR$(0)+CHR$(77) AND AFUN=0 THEN X=X+1:GOSUB 63400:REM RIGHT
1070 IF IN$=CHR$(0)+CHR$(72) AND AFUN=0 THEN Y=Y-1:GOSUB 63400:REM UP
1080 IF IN$=CHR$(0)+CHR$(80) AND AFUN=0 THEN Y=Y+1:GOSUB 63400:REM DOWN
1090 REM ----- MOVE GRID
1100 IF IN$=CHR$(0)+CHR$(75) AND AFUN=1 THEN GOSUB 2200:REM LEFT
1110 IF IN$=CHR$(0)+CHR$(77) AND AFUN=1 THEN GOSUB 2240:REM RIGHT
1120 IF IN$=CHR$(0)+CHR$(72) AND AFUN=1 THEN GOSUB 2280:REM UP
1130 IF IN$=CHR$(0)+CHR$(80) AND AFUN=1 THEN GOSUB 2320:REM DOWN
1140 REM ----- MOVE IMAGE
1150 IF IN$=CHR$(0)+CHR$(75) AND AFUN=2 THEN GOSUB 2400:XOFF=XOFF-4:GOSUB 2900:REM LEFT
1160 IF IN$=CHR$(0)+CHR$(77) AND AFUN=2 THEN GOSUB 2400:XOFF=XOFF+4:GOSUB 2900:REM RIGHT
1170 IF IN$=CHR$(0)+CHR$(72) AND AFUN=2 THEN GOSUB 2400:YOFF=YOFF-4:GOSUB 2900:REM UP
1180 IF IN$=CHR$(0)+CHR$(80) AND AFUN=2 THEN GOSUB 2400:YOFF=YOFF+4:GOSUB 2900:REM DOWN
1190 REM -----
1200 IF IN$=CHR$(0)+CHR$(59) THEN GOSUB 2400:GOSUB 2900:GOTO 1800:REM REDRAW
1210 IF IN$=CHR$(0)+CHR$(60) THEN GOSUB 3000:GOTO 1800:REM SAVE IMAGE
1230 REM
1235 IF IN$=CHR$(0)+CHR$(61) THEN GOSUB 3200:GOTO 2130:REM SELECT AND DRAW FROM PCX FILE
1240 IF IN$=CHR$(0)+CHR$(94) THEN DRAWBPL=DRAWBPL-1:GOSUB 2400:GOSUB 4040:REM CTL F1, ADJUST .ART DRAW
1243 IF IN$=CHR$(0)+CHR$(95) THEN DRAWBPL=DRAWBPL+1:GOSUB 2400:GOSUB 4040:REM CTL F2, ADJUST .ART DRAW
1245 IF IN$=CHR$(0)+CHR$(96) THEN GOSUB 4000:GOTO 2130:REM CTL F3 SELECT AND DRAW FROM .ART FILE
1250 IF IN$=CHR$(0)+CHR$(62) THEN GOSUB 4500:GOTO 2130:REM SAVE TO FILE
1260 REM -----
1270 IF IN$=CHR$(0)+CHR$(63) THEN MEM1X=X:MEM1Y=Y:LOCATE 28,48:PRINT "mem ";MEM1X;MEM1Y;"   ";
1275 IF IN$=CHR$(0)+CHR$(64) THEN X=MEM1X:Y=MEM1Y:GOSUB 63400
1280 IF IN$=CHR$(0)+CHR$(98) THEN MEM2X=X:MEM2Y=Y:LOCATE 29,48:PRINT "m2  ";MEM2X;MEM2Y;"   ";
1285 IF IN$=CHR$(0)+CHR$(99) THEN X=MEM2X:Y=MEM2Y:GOSUB 63400
1290 REM -----
1300 IF IN$=CHR$(0)+CHR$(65) AND NOT FMODE THEN GOSUB 5800:GOTO 1800:REM FILL BOX AREA
1305 IF IN$=CHR$(0)+CHR$(65) AND FMODE THEN GOSUB 5860:GOTO 1800:REM FILL BOX AREA
1310 IF IN$=CHR$(0)+CHR$(66) AND NOT EMODE THEN GOSUB 6000:GOTO 1800:REM ERASE BOX AREA
1315 IF IN$=CHR$(0)+CHR$(66) AND EMODE THEN GOSUB 6060:GOTO 1800:REM ERASE BOX AREA
1320 IF IN$=CHR$(0)+CHR$(100) THEN GOSUB 6900:GOTO 1800:REM FILL BORDERED AREA
1325 IF IN$=CHR$(0)+CHR$(101) THEN GOSUB 6950:GOTO 1800:REM ERASE BORDERED AREA
1330 REM -----
1335 IF IN$=CHR$(0)+CHR$(67) AND NOT GRID THEN GRID=-1:GOSUB 2400:GOTO 1800 
1340 IF IN$=CHR$(0)+CHR$(67) AND GRID THEN GRID=0:GOSUB 2400:GOTO 1800
1345 IF IN$=CHR$(0)+CHR$(68) THEN GOSUB 8000:GOSUB 2400:GOTO 1800:REM HELP
1350 REM -----
1355 IF IN$=CHR$(16) THEN GOSUB 7000:REM CTRL P=PRINT GRAPHICS SCREEN
1357 REM -----
1360 IF IN$="W" OR IN$="w" THEN GOSUB 6300:GOTO 1800
1370 IF (IN$="D" OR IN$="d") AND NOT INS THEN INS=-1:DEL=0:GOSUB 2600:GOTO 1800
1380 IF (IN$="D" OR IN$="d") AND INS THEN GOSUB 2680:GOTO 1800
1390 IF (IN$="E" OR IN$="e") AND NOT DEL THEN DEL=-1:INS=0:GOSUB 2640:GOTO 1800
1400 IF (IN$="E" OR IN$="e") AND DEL THEN GOSUB 2680:GOTO 1800
1410 IF IN$="X" OR IN$="x" THEN GOSUB 2680:GOTO 1800
1415 IF IN$=" " THEN GOSUB 2680:GOTO 1800
1420 REM -----
1425 IF (IN$="L" OR IN$="l") AND NOT LMODE THEN GOSUB 6500:GOTO 1800
1430 IF (IN$="L" OR IN$="l") AND LMODE THEN GOSUB 6560:GOTO 1800
1435 IF (IN$="C" OR IN$="c") AND NOT CMODE THEN GOSUB 6700:GOTO 1800
1440 IF (IN$="C" OR IN$="c") AND CMODE THEN GOSUB 6760:GOTO 1800
1450 REM -----
1460 IF IN$<>CHR$(27) THEN 1500
1470 LOCATE 2,68:PRINT "EXIT? (Y/N)";
1480 IN$=INKEY$:IF IN$="" THEN 1480
1490 IF IN$="y" OR IN$="Y" THEN CLS:END
1500 LOCATE 2,68:PRINT "Filename:  ";
1510 REM -----
1520 IF (IN$="A" OR IN$="a") AND AFUN=2 THEN GOSUB 2700:GOTO 1800
1540 IF (IN$="A" OR IN$="a") AND AFUN=0 THEN GOSUB 2720:GOTO 1800
1560 IF (IN$="A" OR IN$="a") AND AFUN=1 THEN GOSUB 2740:GOTO 1800
1580 REM
1790 REM ----- DISPLAY SOME STUFF
1800 LOCATE 28,2:PRINT "X";X;"  ";
1810 LOCATE 28,8:PRINT "Y";Y;"  ";
1830 IF POINT (X,Y)=WHITE THEN LINE(135,434)-(144,443),CYAN,BF
1840 IF POINT (X,Y)<>WHITE THEN LINE(127,434)-(152,443),0,BF
1850 REM -----
1860 IF LEFT THEN DEL=0:GOSUB 2600 
1870 IF RIGHT THEN INS=0:GOSUB 2640 
1880 IF NOT RIGHT AND NOT LEFT AND NOT INS AND NOT DEL THEN GOSUB 2680 
1900 REM ----- SKIP THE REST IF WE HAVE NOT MOVED
1910 IF X=OLDX AND Y=OLDY THEN 1000
1950 REM ----- SET OR ERASE POINTS
1960 IF NOT LEFT AND NOT RIGHT AND NOT INS AND NOT DEL THEN 1000
1970 IF LEFT OR INS THEN POINTCOLOR=WHITE
1980 IF RIGHT OR DEL THEN POINTCOLOR=0
1990 GOSUB 63200:REM HIDE MOUSE CURSOR
2000 IF LWIDTH$="1" THEN PSET(X,Y),POINTCOLOR:GOTO 2100
2010 LINE(X-LWID,Y-LWID)-(X+LWID,Y+LWID),POINTCOLOR,BF
2100 GOSUB 63100:REM SHOW MOUSE CURSOR
2110 GOTO 1000 
2120 REM ----- END OF MAIN LOOP
2130 T=TIMER
2140 IF TIMER<T+.5 THEN 2140
2150 GOTO 1000
2180 REM ---------------------------------------------------------------------
2190 REM ----- CHANGE GRID SIZE
2200 LRX=LRX-8
2205 XX=(LRX+1) MOD 8:IF XX<>0 THEN LRX=LRX+XX
2210 IF LRX<15 THEN LRX=15
2215 GOSUB 2400:REM DRAW GRID
2220 RETURN
2240 LRX=LRX+8
2245 XX=(LRX+1) MOD 8:IF XX<>0 THEN LRX=LRX-XX
2250 IF LRX>XMAX THEN LRX=XMAX
2255 GOSUB 2400:REM DRAW GRID
2260 RETURN
2280 LRY=LRY-8
2285 YY=(LRY+1) MOD 8:IF YY<>0 THEN LRY=LRY+YY
2290 IF LRY<15 THEN LRY=15
2295 GOSUB 2400:REM DRAW GRID
2300 RETURN
2320 LRY=LRY+8
2325 YY=(LRY+1) MOD 8:IF YY<>0 THEN LRY=LRY-YY
2330 IF LRY>YMAX THEN LRY=YMAX
2335 GOSUB 2400:REM DRAW GRID
2340 RETURN
2350 REM ----- DRAW GRID
2400 GOSUB 63200:REM HIDE MOUSE CURSOR
2405 LINE(0,0)-(XMAX,YMAX),0,BF
2407 LINE(0,0)-(639,479),WHITE,B
2410 IF NOT GRID THEN 2450
2420 FOR YY=0 TO 416 STEP 16:LINE(0,YY)-(512,YY),8:NEXT YY
2425 FOR XX=0 TO 512 STEP 16:LINE(XX,0)-(XX,416),8:NEXT XX
2427 LINE(0,0)-(639,479),WHITE,B
2430 FOR YY=0 TO LRY STEP 16:LINE(0,YY)-(LRX,YY),CYAN:NEXT YY
2440 FOR XX=0 TO LRX STEP 16:LINE (XX,0)-(XX,LRY),CYAN:NEXT XX
2450 LINE(0,0)-(LRX,LRY),CYAN,B
2460 LINE(519,0)-(519,479),WHITE
2465 LINE(0,424)-(519,424),WHITE
2490 BPL=(LRX+1)/8:REM BYTES PER LINE
2500 TOPLIMIT=0:BOTTOMLIMIT=LRY:LEFTLIMIT=0:RIGHTLIMIT=LRX
2510 GOSUB 63700:REM SET MOUSE CURSOR LIM.
2520 GOSUB 63100:REM SHOW MOUSE CURSOR
2530 LOCATE 28,24:PRINT "X size";LRX+1;"   ";
2535 LOCATE 29,24:PRINT "Y size";LRY+1;"   ";
2540 LOCATE 28,38:PRINT BPL;"     ";
2545 LOCATE 29,38:PRINT "bytes";
2550 RETURN
2590 REM ----- DRAW/ERASE SELECTION
2600 LINE(112,463)-(166,466),GREEN,BF
2610 LOCATE 29,15:PRINT "drawing";
2620 GOSUB 63200:PSET(X,Y),WHITE:GOSUB 63100
2625 GOSUB 2800:REM IMAGE NOT SAVED MESSAGE
2630 RETURN
2640 LINE(112,463)-(166,466),RED,BF
2650 LOCATE 29,15:PRINT "erasing";
2660 GOSUB 63200:PSET(X,Y),0:GOSUB 63100
2665 GOSUB 2800:REM IMAGE NOT SAVED MESSAGE
2670 RETURN
2680 LINE(112,446)-(166,466),0,BF
2685 INS=0:DEL=0
2690 RETURN
2695 REM ----- ARROW FUNCTION MESSAGES
2700 AFUN=0:LOCATE 7,68:PRINT "move X,Y   ";
2705 LINE(AULX,AULY)-(ALRX,ALRY),YELLOW,B
2710 RETURN
2720 AFUN=1:LOCATE 7,68:PRINT "grid size  ";
2725 LINE(AULX,AULY)-(ALRX,ALRY),CYAN,B
2730 RETURN
2740 AFUN=2:LOCATE 7,68:PRINT "shift image";
2745 LINE(AULX,AULY)-(ALRX,ALRY),RED,B
2750 RETURN
2790 REM ----- IMAGE MESSAGE
2800 LOCATE 29,48:PRINT "Image not saved";
2805 RETURN
2820 LOCATE 29,48:PRINT "               ";
2825 RETURN
2890 REM ---------------------------------------------------------------------
2895 REM ----- REDRAW FROM IMAGE ARRAY
2900 GOSUB 63200:REM HIDE MOUSE CURSOR
2905 FOR Y%=0 TO RLRY
2910  XX%=((RLRX+1)/8)-1
2915  FOR XB%=0 TO XX%
2920   X%=XB%*8
2925   IF (IMAGE%(XB%,Y%) AND 128)<>128 THEN PSET(X%+XOFF,Y%+YOFF),WHITE
2930   X%=X%+1:IF (IMAGE%(XB%,Y%) AND 64)<>64 THEN PSET(X%+XOFF,Y%+YOFF),WHITE
2935   X%=X%+1:IF (IMAGE%(XB%,Y%) AND 32)<>32 THEN PSET(X%+XOFF,Y%+YOFF),WHITE
2940   X%=X%+1:IF (IMAGE%(XB%,Y%) AND 16)<>16 THEN PSET(X%+XOFF,Y%+YOFF),WHITE
2945   X%=X%+1:IF (IMAGE%(XB%,Y%) AND 8)<>8 THEN PSET(X%+XOFF,Y%+YOFF),WHITE
2950   X%=X%+1:IF (IMAGE%(XB%,Y%) AND 4)<>4 THEN PSET(X%+XOFF,Y%+YOFF),WHITE
2955   X%=X%+1:IF (IMAGE%(XB%,Y%) AND 2)<>2 THEN PSET(X%+XOFF,Y%+YOFF),WHITE
2960   X%=X%+1:IF (IMAGE%(XB%,Y%) AND 1)<>1 THEN PSET(X%+XOFF,Y%+YOFF),WHITE
2965  NEXT XB%
2970 NEXT Y%
2975 GOSUB 63100:REM SHOW MOUSE CURSOR
2980 RETURN
2995 REM ----- SAVE IMAGE ARRAY
3000 GOSUB 63200:REM HIDE MOUSE CURSOR
3010 LOCATE 2,68:PRINT "SavingImage";
3015 FOR Y%=0 TO LRY
3020  XX%=((LRX+1)/8)-1
3025  FOR XB%=0 TO XX%
3030   X%=XB%*8:B%=0
3035   IF POINT(X%,Y%)<>WHITE THEN B%=B%+128
3040   X%=X%+1:IF POINT(X%,Y%)<>WHITE THEN B%=B%+64
3045   X%=X%+1:IF POINT(X%,Y%)<>WHITE THEN B%=B%+32
3050   X%=X%+1:IF POINT(X%,Y%)<>WHITE THEN B%=B%+16
3055   X%=X%+1:IF POINT(X%,Y%)<>WHITE THEN B%=B%+8
3060   X%=X%+1:IF POINT(X%,Y%)<>WHITE THEN B%=B%+4
3065   X%=X%+1:IF POINT(X%,Y%)<>WHITE THEN B%=B%+2
3070   X%=X%+1:IF POINT(X%,Y%)<>WHITE THEN B%=B%+1
3075   IMAGE%(XB%,Y%)=B%
3080  NEXT XB%
3085  IF Y% MOD 4<>0 THEN 3095
3090  FOR PX%=0 TO LRX STEP 4:PSET(PX%,Y%),CYAN:NEXT PX%
3095 NEXT Y%
3100 LOCATE 2,68:PRINT "Filename:  ";
3105 GOSUB 63100:REM SHOW MOUSE CURSOR
3110 XOFF=0:YOFF=0
3115 RLRX=LRX:RLRY=LRY
3120 GOSUB 2820:REM ERASE "NOT SAVED" MESSAGE
3125 RETURN
3185 REM ---------------------------------------------------------------------
3190 REM ----- LOAD PCX FILE TO SCREEN
3200 LOCATE 2,68:PRINT "Enter name:";
3210 LOCATE 3,68:PRINT "           ";
3220 LOCATE 3,68,1
3230 LINE INPUT FILENAME$
3240 IF FILENAME$="" THEN 3425
3250 IF LEN(FILENAME$)>8 THEN BEEP:GOTO 3200
3260 FILE$=FILENAME$
3270 FILELOAD=-1:REM GET LRX, LRY ALSO
3280 XOFF=0:YOFF=0
3290 REM -----
3300 ON ERROR GOTO 3400:REM IF DATA FILE DOES NOT EXIST
3310 F$=FILE$+EXT$:OPEN F$ FOR INPUT AS #1:CLOSE #1
3320 ON ERROR GOTO 0
3330 LOCATE 2,68:PRINT "Loading....";
3340 LOCATE 3,68:PRINT "<"+FILE$+">"+SPACE$(10-LEN(FILE$));
3350 GOTO 3450
3360 REM -----
3400 RESUME 3405
3405 ON ERROR GOTO 0
3410 LOCATE 2,68:PRINT "Not found  ";
3415 T=TIMER
3420 IF TIMER<T+2 THEN 3420
3425 LOCATE 2,68:PRINT "Filename:  ";
3430 REM FILE$="TEMP"
3435 LOCATE 3,68:PRINT "<"+FILE$+">"+SPACE$(10-LEN(FILE$));
3440 RETURN
3445 REM ----- DRAW FROM F$
3450 LOCATE ,,0
3455 LOADFLAG=-1
3460 FOR Y%=0 TO YMAX:FOR XB%=0 TO XBMAX:IMAGE%(XB%,Y%)=255:NEXT XB%:NEXT Y%
3465 GOSUB 63200:REM HIDE MOUSE CURSOR
3470 REM -----
3475 OPEN F$ FOR INPUT AS #1
3480 FILELENGTH=LOF(1)
3485 CLOSE #1
3490 OPEN "R",#1,F$,1
3495 FIELD #1,1 AS FILEREAD$
3500 REM -----
3505 GET #1,9
3510 LRXLSB=ASC(FILEREAD$)
3515 GET #1,10
3520 LRXMSB=ASC(FILEREAD$)
3525 IF FILELOAD THEN LRX=(LRXMSB*256)+LRXLSB
3530 REM -----
3535 GET #1,11
3540 LRYLSB=ASC(FILEREAD$)
3545 GET #1,12
3550 LRYMSB=ASC(FILEREAD$)
3555 IF FILELOAD THEN LRY=(LRYMSB*256)+LRYLSB
3560 REM -----
3565 GET #1,67
3570 BPLLSB=ASC(FILEREAD$)
3575 GET #1,68
3580 BPLMSB=ASC(FILEREAD$)
3585 DBPL=(BPLMSB*256)+BPLLSB
3590 REM -----
3595 GOSUB 2400:REM DRAW GRID PER LRX,LRY
3600 RECNUM%=129:EX=0
3605 XB%=0:Y%=0
3610 REM -----
3615 GET #1,RECNUM%
3620   LOCATE 4,67:PRINT RECNUM%;
3625   BYTE%=ASC(FILEREAD$)
3630   IF BYTE%>=192 THEN 3660
3635   REPS%=1:GOSUB 3700
3640   IF EX THEN 3800
3645   RECNUM%=RECNUM%+1
3650   IF RECNUM%=FILELENGTH+1 THEN 3800
3655 GOTO 3615
3660   REPS%=BYTE%-192
3665   RECNUM%=RECNUM%+1
3670   GOSUB 3700
3675   IF EX THEN 3800
3680   RECNUM%=RECNUM%+1
3685   IF RECNUM%=FILELENGTH+1 THEN 3800
3690 GOTO 3615
3695 REM -----
3700 FOR B%=1 TO REPS%
3705   GET #1,RECNUM%
3710   BYTE%=ASC(FILEREAD$)
3715   IMAGE%(XB%,Y%)=BYTE%
3720   X%=XB%*8
3725   IF (BYTE% AND 128)<>128 THEN PSET(X%,Y%),WHITE
3730   IF (BYTE% AND 64)<>64 THEN PSET(X%+1,Y%),WHITE
3735   IF (BYTE% AND 32)<>32 THEN PSET(X%+2,Y%),WHITE
3740   IF (BYTE% AND 16)<>16 THEN PSET(X%+3,Y%),WHITE
3745   IF (BYTE% AND 8)<>8 THEN PSET(X%+4,Y%),WHITE
3750   IF (BYTE% AND 4)<>4 THEN PSET(X%+5,Y%),WHITE
3755   IF (BYTE% AND 2)<>2 THEN PSET(X%+6,Y%),WHITE
3760   IF (BYTE% AND 1)<>1 THEN PSET(X%+7,Y%),WHITE
3765   XB%=XB%+1
3770   IF XB%>(DBPL-1) THEN XB%=0:Y%=Y%+1
3775   IF RECNUM%=FILELENGTH+1 THEN EX=-1:GOTO 3790
3780   IN$=INKEY$:IF IN$=CHR$(27) THEN EX=-1:GOTO 3790
3785 NEXT B%
3790 RETURN
3795 REM -----
3800 CLOSE #1
3805 LOCATE 4,68:PRINT "           ";
3810 LOCATE 2,68:PRINT "Filename:  ";
3815 LOCATE 3,68:PRINT "<"+FILE$+">"+SPACE$(10-LEN(FILE$));
3820 FILELOAD=0:EX=0
3825 GOSUB 63100:REM SHOW MOUSE CURSOR
3830 RLRX=LRX:RLRY=LRY
3835 GOSUB 2820:REM ERASE "NOT SAVED" MESSAGE
3840 RETURN
3980 REM ---------------------------------------------------------------------
3985 REM ?HI RES ART=FF FF 2C 01 2C 01 XLSB XMSB YLSB YMSB 01 00, THEN DATA
3990 REM ----- LOAD FIRST PUBLISHER STANDARD ART FILE TO SCREEN
4000 LOCATE 2,68:PRINT "Enter .ART:";
4002 LOCATE 3,68:PRINT "           ";
4005 LOCATE 3,68,1
4010 LINE INPUT FILE$
4015 IF FILE$="" THEN 4100
4020 IF LEN(FILE$)>8 THEN BEEP:GOTO 4000
4025 FILELOAD=-1:REM GET LRX, LRY ALSO
4030 XOFF=0:YOFF=0:DRAWBPL=16:REM BPL NEEDED?
4035 REM -----
4040 ON ERROR GOTO 4075:REM IF DATA FILE DOES NOT EXIST
4045 ARTF$=FILE$+".ART":OPEN ARTF$ FOR INPUT AS #1:CLOSE #1
4050 ON ERROR GOTO 0
4055 LOCATE 2,68:PRINT "Drawing....";
4060 LOCATE 3,68:PRINT "<"+FILE$+">"+SPACE$(10-LEN(FILE$));
4065 GOTO 4125
4070 REM -----
4075 RESUME 4080
4080 ON ERROR GOTO 0
4085 LOCATE 2,68:PRINT "Not found  ";
4090 T=TIMER
4095 IF TIMER<T+2 THEN 4095
4100 LOCATE 2,68:PRINT "Filename:  ";
4105 FILE$="TEMP"
4110 LOCATE 3,68:PRINT "<"+FILE$+">"+SPACE$(10-LEN(FILE$));
4115 RETURN
4120 REM ----- DRAW FROM ARTF$
4125 LOCATE ,,0
4130 GOSUB 63200:REM HIDE MOUSE CURSOR
4135 REM ---------------------------------
4140 OPEN ARTF$ FOR INPUT AS #1
4145 FILELENGTH=LOF(1)
4150 CLOSE #1
4155 OPEN "R",#1,ARTF$,1
4160 FIELD #1,1 AS FILEREAD$
4165 REM ---------------- BELOW HERE DIFFERENT FROM ORIGINAL
4170 EX=0:XB=0:Y=2
4175 GET #1,3
4180 LRXLSB=ASC(FILEREAD$)
4185 GET #1,4
4190 LRXMSB=ASC(FILEREAD$)
4195 IF FILELOAD THEN LRX=(LRXMSB*256)+LRXLSB
4200 REM -----
4205 GET #1,7
4210 LRYLSB=ASC(FILEREAD$)
4215 GET #1,8
4220 LRYMSB=ASC(FILEREAD$)
4225 IF FILELOAD THEN LRY=(LRYMSB*256)+LRYLSB
4230 REM -----
4235 IF FILELOAD THEN DRAWBPL=INT(LRX/8)
4240 IF FILELOAD THEN GOSUB 2400:REM DRAW GRID PER LRX, LRY
4245 REM -----
4250 RECNUM=9
4255 REM -----
4260 GET #1,RECNUM
4265   GOSUB 4295
4270   IF EX THEN 4375
4275   RECNUM=RECNUM+1
4280   IF RECNUM=FILELENGTH+1 THEN 4375
4285 GOTO 4260
4290 REM -----
4295 BYTE=ASC(FILEREAD$)
4300 IF (BYTE AND 128)<>128 THEN PSET((XB*8)-3,Y),WHITE
4305 IF (BYTE AND 64)<>64 THEN PSET((XB*8)-2,Y),WHITE
4310 IF (BYTE AND 32)<>32 THEN PSET((XB*8)-1,Y),WHITE
4315 IF (BYTE AND 16)<>16 THEN PSET((XB*8)-0,Y),WHITE
4320 IF (BYTE AND 8)<>8 THEN PSET((XB*8)+1,Y),WHITE
4325 IF (BYTE AND 4)<>4 THEN PSET((XB*8)+2,Y),WHITE
4330 IF (BYTE AND 2)<>2 THEN PSET((XB*8)+3,Y),WHITE
4335 IF (BYTE AND 1)<>1 THEN PSET((XB*8)+4,Y),WHITE
4340 XB=XB+1
4345 IF XB>(DRAWBPL-1) THEN XB=0:Y=Y+1
4350 REM IF Y>(LRY-1) THEN EX=-1:GOTO 3910
4355 IF RECNUM=FILELENGTH+1 THEN EX=-1:GOTO 4365
4360 IN$=INKEY$:IF IN$<>"" THEN EX=-1:GOTO 4365
4362 RLRX=LRX:RLRY=LRY
4365 RETURN
4370 REM ----------------- ABOVE HERE DIFFERENT FROM ORIGINAL
4375 CLOSE #1
4380 LOCATE 4,68:PRINT "           ";
4385 LOCATE 2,68:PRINT "Filename:  ";
4390 LOCATE 3,68:PRINT "<"+FILE$+">"+SPACE$(10-LEN(FILE$));
4395 FILELOAD=0:EX=0
4400 GOSUB 63100:REM SHOW MOUSE CURSOR
4405 GOSUB 2820:REM ERASE "NOT SAVED" MESSAGE
4410 RETURN
4480 REM -----------------------------------------------
4490 REM ----- SAVE SCREEN AS BLACK AND WHITE .PCX FILE
4500 LOCATE 2,68:PRINT "Saving.....";
4510 LOCATE 3,68:PRINT "<"+FILE$+">"+SPACE$(10-LEN(FILE$));
4520 GOSUB 63200:REM HIDE MOUSE CURSOR
4530 REM LINE(0,0)-(LRX,LRY),0,B
4540 GOSUB 4650
4550 XOFF=0:YOFF=0
4560 LOCATE 4,68:PRINT "           ";
4565 IF EX THEN EX=0:GOTO 4610
4570 REM -----
4580 LOCATE 2,68:PRINT "Redrawing..";
4590 LOCATE 3,68:PRINT "<"+FILE$+">"+SPACE$(10-LEN(FILE$));
4600 GOSUB 3450:REM DRAW
4610 LOCATE 2,68:PRINT "Filename:  ";
4620 GOSUB 63100:REM SHOW MOUSE CURSOR
4630 RETURN
4645 REM ----- FORM HEADER
4650 DIM H(128)
4655 H(0)=&HA:REM ZSOFT PCX FLAG
4660 H(1)=5:REM VERSION 0=PC PAINTBRUSH 2.5, 2=2.8 WITH PALETTE,
4665 REM    3=2.8 WITHOUT PALETTE, 4=WINDOWS, 5=3.0 AND UP,
4670 REM    PC PAINTBRUSH IV, IV+, 5 REQUIRED FOR WINDOWS 95
4675 H(2)=1:REM RUN LENGTH ENCODING=1
4680 H(3)=1:REM BITS PER PIXEL EACH PLANE 1,2,4,8
4685 REM -----
4690 H(4)=0:REM UPPER LEFT X LSB
4695 H(5)=0:REM MSB
4700 H(6)=0:REM UPPER LEFT Y LSB
4705 H(7)=0:REM MSB
4710 REM -----
4715 H(8)=LRX MOD 256:REM LOWER RIGHT X CO-ORD LSB
4720 H(9)=INT(LRX/256):REM MSB
4725 H(10)=LRY MOD 256:REM LOWER RIGHT Y CO-ORD LSB
4730 H(11)=INT(LRY/256):REM MSB
4735 REM -----
4740 XRES=640:YRES=480
4745 H(12)=XRES MOD 256:REM PRINTED HORIZONTAL RES IN BPI, LSB (75-100?)
4750 H(13)=INT(XRES/256):REM MSB
4755 H(14)=YRES MOD 256:REM PRINTED VERTICAL RES IN BPI, LSB
4760 H(15)=INT(YRES/256):REM MSB
4765 REM -----
4770 H(16)=0:H(17)=0:H(18)=0            :REM LIKE ALCHEMY PROGRAMS (VERSION=5)
4775 H(19)=&HFF:H(20)=&HFF:H(21)=&HFF             :REM BLACK AND WHITE PALETTE
4785 FOR A%=22 TO 63
4790   H(A%)=0
4795 NEXT A%
4850 REM -----
4855 H(64)=0:REM RESERVED FOR ZSOFT, VIDEO BOARD BIOS VALUE?
4860 H(65)=1:REM COLOR/GREYSCALE PLANES,1,4,OR 3=24 BIT
4865 REM BPL=(LRX+1)/8:REM BYTES PER LINE (SET BY GRID SIZE ROUTINE)
4870 H(66)=BPL MOD 256:REM LSB
4875 H(67)=INT(BPL/256):REM MSB
4880 H(68)=1:REM HEADER PALETTE INTERPRETATION LSB, 1= COLOR, 2=GREY
4885 H(69)=0:REM MSB
4890 SCREENWIDTH=639:REM # PIXELS HORIZONTAL-1
4895 H(70)=SCREENWIDTH MOD 256:REM LSB
4900 H(71)=INT(SCREENWIDTH/256):REM MSB
4905 SCREENHEIGHT=479:REM #PIXELS VERTICAL-1
4910 H(72)=SCREENHEIGHT MOD 256:REM LSB
4915 H(73)=INT(SCREENHEIGHT/256):REM MSB
4920 REM -----
4925 FOR A%=74 TO 127
4930   H(A%)=0
4935 NEXT A%
5180 REM ----- FILL ARRAY WITH DATA
5200 XX=(LRX+1)/8:YY=LRY+1
5210 DIM GFXDAT%(XX,YY)
5220 FOR Y%=0 TO LRY
5230  FOR XBYTE%=0 TO BPL-1
5240   XB%=XBYTE%*8
5250   BYTE%=0
5260   X%=XB%+0:IF POINT(X%,Y%)<>WHITE THEN BYTE%=BYTE%+128:PSET(X%,Y%),WHITE ELSE PSET(X%,Y%),0
5270   X%=XB%+1:IF POINT(X%,Y%)<>WHITE THEN BYTE%=BYTE%+64:PSET(X%,Y%),WHITE ELSE PSET(X%,Y%),0
5280   X%=XB%+2:IF POINT(X%,Y%)<>WHITE THEN BYTE%=BYTE%+32:PSET(X%,Y%),WHITE ELSE PSET(X%,Y%),0
5290   X%=XB%+3:IF POINT(X%,Y%)<>WHITE THEN BYTE%=BYTE%+16:PSET(X%,Y%),WHITE ELSE PSET(X%,Y%),0
5300   X%=XB%+4:IF POINT(X%,Y%)<>WHITE THEN BYTE%=BYTE%+8:PSET(X%,Y%),WHITE ELSE PSET(X%,Y%),0
5310   X%=XB%+5:IF POINT(X%,Y%)<>WHITE THEN BYTE%=BYTE%+4:PSET(X%,Y%),WHITE ELSE PSET(X%,Y%),0
5320   X%=XB%+6:IF POINT(X%,Y%)<>WHITE THEN BYTE%=BYTE%+2:PSET(X%,Y%),WHITE ELSE PSET(X%,Y%),0
5330   X%=XB%+7:IF POINT(X%,Y%)<>WHITE THEN BYTE%=BYTE%+1:PSET(X%,Y%),WHITE ELSE PSET(X%,Y%),0
5340   GFXDAT%(XBYTE%,Y%)=BYTE%
5360   IN$=INKEY$:IF IN$=CHR$(27) THEN EX=-1:GOTO 5620
5370  NEXT XBYTE%
5380 NEXT Y%
5390 REM ----- WRITE HEADER
5400 F$=FILE$+EXT$
5410 OPEN F$ FOR OUTPUT AS #2
5420 FOR A%=0 TO 127
5430   PRINT #2,CHR$(H(A%));
5440 NEXT A%
5450 REM ----- WRITE PCX DATA
5460 FOR Y%=0 TO LRY
5470   LOCATE 4,67:PRINT STR$(Y%+1);" :";STR$(LRY+1);
5480   XBYTE%=0
5490     REP=0:NUMREPS%=0
5500     A%=GFXDAT%(XBYTE%,Y%)
5510     XBYTE%=XBYTE%+1
5520       IF XBYTE%=BPL THEN 5650
5530         B%=GFXDAT%(XBYTE%,Y%)
5540       IF B%<>A% THEN 5580
5550         REP=-1:NUMREPS%=NUMREPS%+1
5560         IF NUMREPS%=63 THEN 5600
5570    GOTO 5510
5580      IF NOT REP THEN 5620
5590        NUMREPS%=NUMREPS%+1
5600        PRINT #2,CHR$(192+NUMREPS%);CHR$(A%);
5610        GOTO 5490
5620      IF A%>=192 THEN PRINT #2,CHR$(193);
5630      PRINT #2,CHR$(A%);
5640    GOTO 5500
5650      IF NOT REP THEN 5680
5660        PRINT #2,CHR$(192+NUMREPS%+1);CHR$(A%);
5670        GOTO 5700
5680      IF A%>=192 THEN PRINT #2,CHR$(193);
5690        PRINT #2,CHR$(A%);
5700 NEXT Y%
5710 REM -----
5720 CLOSE
5730 ERASE H:ERASE GFXDAT%
5740 GOSUB 2820:REM ERASE "NOT SAVED" MESSAGE
5750 RETURN
5790 REM ---------------------- FILL A BOX AREA ------------------------
5800 LOCATE 2,68:PRINT "StartFill  ";
5810 F1X=X:F1Y=Y:FMODE=-1
5820 GOSUB 63200:REM HIDE MOUSE CURSOR
5830 PSET(F1X,F1Y),YELLOW
5840 GOSUB 63100:REM SHOW MOUSE CURSOR
5850 IN$="":RETURN
5860 LOCATE 2,68:PRINT "Filename:  ";
5870 F2X=X:F2Y=Y:FMODE=0
5880 GOSUB 63200:REM HIDE MOUSE CURSOR
5890 LINE (F1X,F1Y)-(F2X,F2Y),WHITE,BF
5900 GOSUB 63100:REM SHOW MOUSE CURSOR
5910 IN$=""
5920 GOSUB 2800:REM IMAGE NOT SAVED MESSAGE
5930 RETURN
5990 REM ---------------------- ERASE A BOX AREA ---------------------
6000 LOCATE 2,68:PRINT "StartErase ";
6010 E1X=X:E1Y=Y:EMODE=-1
6020 GOSUB 63200:REM HIDE MOUSE CURSOR
6030 PSET(E1X,E1Y),YELLOW
6040 GOSUB 63100:REM SHOW MOUSE CURSOR
6050 IN$="":RETURN
6060 LOCATE 2,68:PRINT "Filename:  ";
6070 E2X=X:E2Y=Y:EMODE=0
6080 GOSUB 63200:REM HIDE MOUSE CURSOR
6090 LINE (E1X,E1Y)-(E2X,E2Y),0,BF
6100 GOSUB 63100:REM SHOW MOUSE CURSOR
6110 IN$=""
6120 GOSUB 2800:REM IMAGE NOT SAVED MESSAGE
6130 RETURN
6290 REM ----------------------- DRAWING WIDTH -------------------------------
6300 IF LWIDTH$="1" THEN LWIDTH$="3":LWID=1:GOTO 6400
6310 IF LWIDTH$="3" THEN LWIDTH$="5":LWID=2:GOTO 6400
6320 IF LWIDTH$="5" THEN LWIDTH$="7":LWID=3:GOTO 6400
6330 IF LWIDTH$="7" THEN LWIDTH$="9":LWID=4:GOTO 6400
6340 IF LWIDTH$="9" THEN LWIDTH$="11":LWID=5:GOTO 6400
6350 IF LWIDTH$="11" THEN LWIDTH$="13":LWID=6:GOTO 6400
6360 IF LWIDTH$="13" THEN LWIDTH$="1":LWID=0:GOTO 6400
6400 LOCATE 29,2:PRINT "width=";LWIDTH$;" ";
6410 RETURN
6490 REM ------------------------- DRAW LINE ---------------------------------
6500 LOCATE 2,68:PRINT "StartLine  ";
6510 L1X=X:L1Y=Y:LMODE=-1
6520 GOSUB 63200:REM HIDE MOUSE CURSOR
6530 PSET(L1X,L1Y),YELLOW
6540 GOSUB 63100:REM SHOW MOUSE CURSOR
6550 IN$="":RETURN
6560 LOCATE 2,68:PRINT "Filename:  ";
6570 L2X=X:L2Y=Y:LMODE=0
6580 GOSUB 63200:REM HIDE MOUSE CURSOR
6590 LINE(L1X,L1Y)-(L2X,L2Y),WHITE:GOTO 6600
6600 GOSUB 63100:REM SHOW MOUSE CURSOR
6610 IN$=""
6620 GOSUB 2800:REM IMAGE NOT SAVED MESSAGE
6630 RETURN
6690 REM ------------------------- DRAW CIRCLE -------------------------------
6700 LOCATE 2,68:PRINT "StartCircle";
6710 CX=X:CY=Y:CMODE=-1
6720 GOSUB 63200:REM HIDE MOUSE CURSOR
6730 PSET(CX,CY),YELLOW
6740 GOSUB 63100:REM SHOW MOUSE CURSOR
6750 IN$="":RETURN
6760 LOCATE 2,68:PRINT "Filename:  ";
6770 GOSUB 63200:REM HIDE MOUSE CURSOR
6780 CXC=ABS(CX-X):CYC=ABS(CY-Y)
6790 IF CXC>CYC THEN RADIUS=CXC ELSE RADIUS=CYC   :REM CYC*2.49 FOR CGA
6800 CIRCLE (CX,CY),RADIUS,WHITE:CMODE=0
6810 GOSUB 63100:REM SHOW MOUSE CURSOR
6820 IN$=""
6830 GOSUB 2800:REM IMAGE NOT SAVED MESSAGE
6840 RETURN
6890 REM ---------------------- FILL A DRAWN AREA --------------------
6900 GOSUB 63200:REM HIDE MOUSE CURSOR
6910 PSET (X,Y),0:PAINT (X,Y),WHITE,WHITE
6920 GOSUB 63100:REM SHOW MOUSE CURSOR
6930 GOSUB 2800:REM IMAGE NOT SAVED MESSAGE
6935 RETURN
6940 REM ---------------------- ERASE A DRAWN AREA -------------------
6950 GOSUB 63200:REM HIDE MOUSE CURSOR
6960 PSET (X,Y),WHITE:PAINT (X,Y),0,0
6970 GOSUB 63100:REM SHOW MOUSE CURSOR
6980 GOSUB 2800:REM IMAGE NOT SAVED MESSAGE
6985 RETURN
6990 REM ------------------------- PRINT GRAPHICS ----------------------------
7000 LOCATE 2,68:PRINT "Printing..";
7010 LOCATE 3,68:PRINT "<"+FILE$+">"+SPACE$(10-LEN(FILE$));
7020 GOSUB 63200:REM HIDE MOUSE CURSOR
7030 WIDTH "LPT1:",255
7040 LPRINT CHR$(27)+"3"+CHR$(15);:REM 20/216" LINE FEEDS
7050 FOR Y=0 TO 479 STEP 8:REM 60 LINES OF 8 PIXELS
7060   LPRINT CHR$(27)+"L"+CHR$(128)+CHR$(2);:REM 640 MOD 256,INT(640/256)
7070   FOR X=0 TO 639
7080     PBYTE=0
7090     IF POINT(X,Y)<>0 THEN PBYTE=PBYTE+128
7100     IF POINT(X,Y+1)<>0 THEN PBYTE=PBYTE+64
7110     IF POINT(X,Y+2)<>0 THEN PBYTE=PBYTE+32
7120     IF POINT(X,Y+3)<>0 THEN PBYTE=PBYTE+16
7130     IF POINT(X,Y+4)<>0 THEN PBYTE=PBYTE+8
7140     IF POINT(X,Y+5)<>0 THEN PBYTE=PBYTE+4
7150     IF POINT(X,Y+6)<>0 THEN PBYTE=PBYTE+2
7160     IF POINT(X,Y+7)<>0 THEN PBYTE=PBYTE+1
7170     LPRINT CHR$(PBYTE);
7180   NEXT X
7190   LPRINT CHR$(10);
7200 NEXT Y
7210 LPRINT CHR$(10);
7220 LOCATE 2,68:PRINT "Filename:  ";
7230 LOCATE 3,68:PRINT "<"+FILE$+">"+SPACE$(10-LEN(FILE$));
7240 GOSUB 63100:REM SHOW MOUSE CURSOR
7250 RETURN
7990 REM -------------------------  HELP SCREEN ------------------------------
8000 LINE(1,1)-(XMAX-1,YMAX-1),0,BF
8010 LOCATE 02,4:PRINT "      DRAWPCX  version 11/2/95  Copyright (c) 1995         "
8020 LOCATE 03,4:PRINT "    Gary Peek  3201 Highgate  St. Charles, MO  63301       "
8030 LOCATE 04,4:PRINT "                                                           "
8040 LOCATE 05,4:PRINT "  This program is a simple drawing and editing utility     "
8050 LOCATE 06,4:PRINT "  for black and white PCX formatted graphic files. It      "
8060 LOCATE 07,4:PRINT "  will allow you to read PCX formatted files, perform      "
8070 LOCATE 08,4:PRINT "  limited drawing functions, edit images pixel by pixel,   "
8080 LOCATE 09,4:PRINT "       and write the images to PCX formatted files.        "
8090 LOCATE 10,4:PRINT "                                                           "
8100 LOCATE 11,4:PRINT "  Explanations of commands:                                "
8110 LOCATE 12,4:PRINT "  A  Arrow keys move x,y or set grid size or shift image.  "
8120 LOCATE 13,4:PRINT "  D & E    Draw and erase pixels based on `width'.         "
8130 LOCATE 14,4:PRINT "  SPACE    Stop drawing or erasing pixels.                 "
8140 LOCATE 15,4:PRINT "  W  Set width of drawing and erasing from 1 to 13.        "
8150 LOCATE 16,4:PRINT "  L  Draw line, first L=start line, second=end line.       "
8160 LOCATE 17,4:PRINT "  C  Draw circle, first C=center, second=circumference.    "
8170 LOCATE 18,4:PRINT "  F1 & F2  Save image in current grid, redraw that image.  "
8180 LOCATE 19,4:PRINT "  F3 & F4  Load from PCX file, save image to PCX file.     "
8190 LOCATE 20,4:PRINT "  F5 & F6  Remember X,Y position, return to position.      "
8200 LOCATE 21,4:PRINT "  F7 & F8  Fill and erase rectangular areas. First key     "
8210 LOCATE 22,4:PRINT "           sets one corner, next key sets other corner.    "
8220 LOCATE 23,4:PRINT "  F9       Turn grid on and off.                           "
8230 LOCATE 24,4:PRINT "                                                           "
8240 LOCATE 25,4:PRINT "                  hit any key to continue                  "
8270 IN$=INKEY$:IF IN$="" THEN 8270
8300 RETURN
61960 REM ********************************************************************
61965 REM ------------------------- GET MONITOR ------------------------------
61970 REM
61975 REM This routine finds the type of video monitor hardware installed.
61980 REM It requires that the assembly language interface be installed.
61985 REM
61990 REM exit with - MONITOR$="MONO","HERC","CGA","EGA",or"VGA", monitor used
61995 REM
62000 DEF SEG=0:STATUS=PEEK(&H463):DEF SEG
62005 IF STATUS<>&HB4 THEN 62040
62010 STATUS=(INP(&H3BA) AND &H80)
62015 FOR DELAYLOOP=1 TO 30000
62020 IF (INP(&H3BA) AND &H80)<>STATUS THEN MONITOR$="HERC":RETURN
62025 NEXT DELAYLOOP
62030 MONITOR$="MONO":RETURN
62035 REM -----
62040 REGAX%=&H1A00
62045 INTERRUPT%=&H10:GOSUB 65000:REM CALL ASM
62050 IF (REGAX% AND &HFF)=&H1A THEN MONITOR$="VGA":RETURN
62055 REM -----
62060 REGAX%=&H1200:REGBX%=&H10
62065 INTERRUPT%=&H10:GOSUB 65000:REM CALL ASM
62070 IF (REGBX% AND &HFF)=&H10 THEN MONITOR$="CGA":RETURN
62075 REM -----
62080 MONITOR$="EGA":RETURN
62085 REM
62110 REM ********************************************************************
62115 REM ------------------------- MOUSE ROUTINES ---------------------------
62120 REM
62125 REM The following routines provide access to some mouse function calls.
62130 REM They require that the assembly language interface be installed.
62135 REM
62140 REM
62145 REM                
62150 REM                
62155 REM                63000   hardware reset and status
62160 REM                63100   show cursor
62165 REM                63200   hide cursor
62170 REM                63300   get button status and mouse position
62175 REM                63400   set cursor position
62180 REM                63500   get button press info
62185 REM                63600   get button release info
62190 REM                63700   set cursor limits
62195 REM                63800   set graphics cursor
62200 REM                
62205 REM                64000   set text cursor
62210 REM                64100   read motion counters
62215 REM                64200   
62220 REM                64300   
62225 REM                64400   
62230 REM                64500   
62235 REM                64600   set sensitivity and double speed
62240 REM                64700   
62245 REM                64800   
62250 REM                64900   get driver version, type, IRQ
62255 REM
62260 REM
62265 REM
62270 REM ********************************************************************
62275 REM ------------------- MOUSE - RESET AND STATUS -----------------------
62280 REM
62285 REM exit with - STATUS = -1 if mouse found and reset, otherwise 0
62290 REM             BUTTONS = number of buttons
62295 REM
63000 REGAX%=0:REGBX%=0:REGCX%=0:REGDX%=0
63005 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM
63010 STATUS=REGAX%:BUTTONS=REGBX%
63015 RETURN
63020 REM
63085 REM ********************************************************************
63090 REM ------------------- MOUSE - SHOW CURSOR ----------------------------
63095 REM
63100 REGAX%=1:INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM
63105 RETURN
63110 REM
63185 REM ********************************************************************
63190 REM ------------------- MOUSE - HIDE CURSOR ----------------------------
63195 REM
63200 REGAX%=2:INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM
63205 RETURN
63210 REM
63270 REM ********************************************************************
63275 REM ---------- MOUSE - GET CURSOR POSITION AND BUTTON STATUS -----------
63280 REM
63285 REM exit with - X and Y = cursor coordinates
63290 REM             LEFT, RIGHT, or BOTH = true for buttons pressed
63295 REM
63300 REGAX%=3
63305 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM
63310 X=REGCX%:Y=REGDX%
63315 REM -----
63320 LEFT=0:RIGHT=0:BOTH=0
63325 IF (REGBX% AND 7)=0 THEN RETURN
63330 T=TIMER
63335 IF TIMER<T+DELAY THEN 63335
63340 IF (REGBX% AND 7)=1 THEN LEFT=-1
63345 IF (REGBX% AND 7)=2 THEN RIGHT=-1
63350 IF (REGBX% AND 7)=3 THEN BOTH=-1
63355 RETURN
63360 REM
63375 REM ********************************************************************
63380 REM ------------------- MOUSE - SET CURSOR POSITION --------------------
63385 REM
63390 REM enter with - X and Y = cursor coordinates
63395 REM
63400 REGAX%=4:REGCX%=X:REGDX%=Y
63405 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM
63410 RETURN
63415 REM
63460 REM ********************************************************************
63465 REM ------------------- MOUSE - GET BUTTON PRESS INFO ------------------
63470 REM
63475 REM enter with - BUTTON = 0 (left) or 1 (right), which button to get
63480 REM exit with  - STATUS = 1 (left), 2 (right), 3 (both), current status
63485 REM              BUTTONS = number of button presses since last called
63490 REM              XPOS and YPOS = coordinates at last press
63495 REM
63500 REGAX%=5:REGBX%=BUTTON
63505 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM
63510 STATUS=REGAX%:BUTTONS=REGBX%:XPOS=REGCX%:YPOS=REGDX%
63515 RETURN
63520 REM
63560 REM ********************************************************************
63565 REM ------------------- MOUSE - GET BUTTON RELEASE INFO ----------------
63570 REM
63575 REM enter with - BUTTON = 0 (left) or 1 (right), which button to get
63580 REM exit with  - STATUS = 1 (left), 2 (right), 3 (both), current status
63585 REM              BUTTONS = number of button releases since last called
63590 REM              XPOS and YPOS = coordinates at last release
63595 REM
63600 REGAX%=6:REGBX%=BUTTON
63605 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM
63610 STATUS=REGAX%:BUTTONS=REGBX%:XPOS=REGCX%:YPOS=REGDX%
63615 RETURN
63620 REM
63670 REM ********************************************************************
63675 REM ------------------- MOUSE - SET CURSOR LIMITS ----------------------
63680 REM
63685 REM enter with - LEFTLIMIT, RIGHTLIMIT, TOPLIMIT, BOTTOMLIMIT
63690 REM              (cursor limits in X and Y coordinates)
63695 REM
63700 REGAX%=7:REGBX%=0:REGCX%=LEFTLIMIT:REGDX%=RIGHTLIMIT:REM HORIZONTAL
63705 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM
63710 REM -----
63715 REGAX%=8:REGBX%=0:REGCX%=TOPLIMIT:REGDX%=BOTTOMLIMIT:REM VERTICAL
63720 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM
63725 RETURN
63730 REM
63785 REM ********************************************************************
63790 REM ------------------- MOUSE - SET GRAPHICS CURSOR --------------------
63795 REM
63800 DIM MOUSECURSOR%(32):RESTORE 63900
63805 FOR CURSLOOP%=1 TO 32
63810   READ BINARY$
63815   BINVALUE=0:BITVALUE=1
63820   FOR CHARLOOP%=16 TO 1 STEP -1
63825     IF MID$(BINARY$,CHARLOOP%,1)="1" THEN BINVALUE=BINVALUE+BITVALUE
63830     BITVALUE=BITVALUE*2
63835   NEXT CHARLOOP%
63840   IF BINVALUE>32767 THEN BINVALUE=BINVALUE-65536!
63845   MOUSECURSOR%(CURSLOOP%)=BINVALUE
63850 NEXT CURSLOOP%
63855 REM
63860 REGAX%=9:REM SET GRAPHICS CURSOR
63865 REGBX%=8:REM HORIZONTAL HOT SPOT
63870 REGCX%=7:REM VERTICAL HOT SPOT
63875 REGDX%=VARPTR(MOUSECURSOR%(1))              :REM VERSION 6.25 AND LATER
63880 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM
63885 RETURN
63890 REM
63895 REM ----- SCREEN MASK
63900 DATA "1111111111111111":REM DATA "1111111111111111":REM 
63901 DATA "1111111111111111":REM DATA "1111111000111111"
63902 DATA "1111111111111111":REM DATA "1111111010111111"
63903 DATA "1111111111111111":REM DATA "1111111010111111"
63904 DATA "1111111111111111":REM DATA "1111111010111111"
63905 DATA "1111111111111111":REM DATA "1111111010111111"
63906 DATA "1111111111111111":REM DATA "1000000111000000"
63907 DATA "1111111111111111":REM DATA "1011111111111110"
63908 DATA "1111111111111111":REM DATA "1000000111000000"
63909 DATA "1111111111111111":REM DATA "1111111010111111"
63910 DATA "1111111111111111":REM DATA "1111111010111111"
63911 DATA "1111111111111111":REM DATA "1111111010111111"
63912 DATA "1111111111111111":REM DATA "1111111010111111"
63913 DATA "1111111111111111":REM DATA "1111111000111111"
63914 DATA "1111111111111111":REM DATA "1111111111111111"
63915 DATA "1111111111111111":REM DATA "1111111111111111"
63916 REM ----- CURSOR MASK
63917 DATA "0000000000000000"
63918 DATA "0000000111000000"
63919 DATA "0000000101000000"
63920 DATA "0000000101000000"
63921 DATA "0000000101000000"
63922 DATA "0000000101000000"
63923 DATA "0111111000111111"
63924 DATA "0100000000000001"
63925 DATA "0111111000111111"
63926 DATA "0000000101000000"
63927 DATA "0000000101000000"
63928 DATA "0000000101000000"
63929 DATA "0000000101000000"
63930 DATA "0000000111000000"
63931 DATA "0000000000000000"
63932 DATA "0000000000000000"
63933 REM
63935 REM
63985 REM ********************************************************************
63990 REM ------------------- MOUSE - SET SOFTWARE TEXT CURSOR ---------------
63995 REM
64000 REGAX%=10:REM SET TEXT CURSOR
64005 REGBX%=0:REM SOFTWARE TEXT CURSOR
64010 REGCX%=&H77FF   :REM TRY &HFFFF
64015 REGDX%=&H7700
64020 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM
64025 RETURN
64030 REM
64035 REM
64075 REM ********************************************************************
64080 REM ------------------- MOUSE - READ MOTION COUNTERS -------------------
64085 REM
64090 REM exit with  - XMICKEY, YMICKEY, mickey counts since last called
64095 REM
64100 REGAX%=11
64105 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM
64110 XMICKEY=REGCX%:YMICKEY=REGDX%
64115 RETURN
64120 REM
64125 REM
64565 REM ********************************************************************
64570 REM ------------------- MOUSE - SET SENSITIVITY ------------------------
64575 REM
64580 REM enter with - XSENS, YSENS = 1 to 100, horiz. and vert. sensitivity
64585 REM              THRESHOLD = 0 to 100, threshold for double speed
64590 REM
64595 REM
64600 REGAX%=26:REGBX%=XSENS:REGCX%=YSENS:REGDX%=THRESHOLD
64605 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM
64610 RETURN
64615 REM
64620 REM
64865 REM ********************************************************************
64870 REM ------------------- MOUSE - GET VERSION, TYPE, IRQ -----------------
64875 REM
64880 REM exit with  - VERSION = mouse driver version number
64885 REM              MOUSETYPE = type of mouse
64890 REM              IRQ = interrupt request
64895 REM
64900 REGAX%=36
64905 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM
64910 VERSION=VAL(HEX$(INT(REGBX%/256))+"."+HEX$(REGBX% MOD 256))
64915 MOUSETYPE=INT(REGCX%/256):IRQ=REGCX% MOD 256
64920 RETURN
64925 REM
64930 REM ********************************************************************
64935 REM ----------- SET UP AND CALL ASSEMBLY LANGUAGE SUBROUTINE -----------
64940 REM
64945 REM This routine sets up and calls a previously loaded general purpose
64950 REM assembly language subroutine to access DOS and other interrupts.
64955 REM Knowledge of how to call these interrupts is required. Interrupts
64960 REM that use only registers AX,BX,CX,DX are the only ones supported.
64965 REM
64970 REM enter with - REGAX%,REGBX%,REGCX%,REGDX%
64975 REM              (registers required for calling the interrupt)
64980 REM              INTERRUPT%, the interrupt to call
64985 REM exit with -  REGAX%,REGBX%,REGCX%,REGDX%
64990 REM              (registers after returning from the interrupt)
64995 REM
65000 DEF SEG=&H4B                         :REM POINT TO SEGMENT
65005 POKE 33,INTERRUPT%                   :REM FILL IN THE INTERRUPT TO CALL
65010 POKE 4,INT(REGAX%/256):POKE 3,REGAX% MOD 256  :REM FILL IN THE REGISTERS
65015 POKE 6,INT(REGBX%/256):POKE 5,REGBX% MOD 256
65020 POKE 8,INT(REGCX%/256):POKE 7,REGCX% MOD 256
65025 POKE 10,INT(REGDX%/256):POKE 9,REGDX% MOD 256
65030 REM ASMSUB=0:CALL ASMSUB          :REM USE THIS LINE FOR THE INTERPRETER
65035 CALL ABSOLUTE(0)              :REM USE THIS LINE FOR THE COMPILER
65040 REGAX=(PEEK(4)*256)+PEEK(3):IF REGAX>32767 THEN REGAX=REGAX-65536!
65045 REGAX%=REGAX
65050 REGBX=(PEEK(6)*256)+PEEK(5):IF REGBX>32767 THEN REGBX=REGBX-65536!
65055 REGBX%=REGBX
65060 REGCX=(PEEK(8)*256)+PEEK(7):IF REGCX>32767 THEN REGCX=REGCX-65536!
65065 REGCX%=REGCX
65070 REGDX=(PEEK(10)*256)+PEEK(9):IF REGDX>32767 THEN REGDX=REGDX-65536!
65075 REGDX%=REGDX
65080 DEF SEG:RETURN                    :REM RETURN TO BASIC SEGMENT
65085 REM
65090 REM
65095 REM ********************************************************************
65100 REM ---------------- LOAD ASSEMBLY LANGUAGE SUBROUTINE -----------------
65105 REM
65110 REM This routine loads the following general purpose assembly language
65115 REM subroutine to access DOS and other interrupts. It is loaded into
65120 REM the area just below the DOS inter-program communication area.
65125 REM
65130 REM               ASSUME  CS:CODE
65135 REM               JMP     HERE
65140 REM 
65145 REM        WORKA  DW      0               ;STORAGE FOR REGISTERS-
65150 REM        WORKB  DW      0               ;BASIC WRITES THESE,
65155 REM        WORKC  DW      0               ;THEN THE INTERRUPT% HAPPENS,
65160 REM        WORKD  DW      0               ;THEN BASIC READS THESE
65165 REM
65170 REM        HERE:	MOV	AX,WORKA        ;GET PARM 1 FROM BASIC
65175 REM        	MOV	BX,WORKB        ;GET PARM 2 FROM BASIC
65180 REM        	MOV	CX,WORKC        ;GET PARM 3 FROM BASIC
65185 REM        	MOV	DX,WORKD        ;GET PARM 4 FROM BASIC
65190 REM               PUSH    DS              ;MAKE ES THE SAME AS DS
65195 REM               POP     ES
65200 REM        	INT	21H             ;DOS (or other) INTERRUPT
65205 REM        	MOV	WORKA,AX        ;SEND PARM 1 TO BASIC
65210 REM        	MOV	WORKB,BX        ;SEND PARM 2 TO BASIC
65215 REM        	MOV	WORKC,CX        ;SEND PARM 3 TO BASIC
65220 REM        	MOV	WORKD,DX        ;SEND PARM 4 TO BASIC
65225 REM               DB      0CBH            ;ASSEMBLER REJECTS "RETF"
65230 REM
65235 REM               CODE ENDS
65240 REM               END
65245 REM
65250 DEF SEG=&H4B:RESTORE 65270
65255 FOR I=0 TO 53:READ B:POKE I,B:NEXT I
65260 DEF SEG:RETURN
65265 REM -----
65270 DATA &HEB,&H09,&H90
65275 DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00       :REM REGISTERS AX-DX
65280 DATA &H2E,&HA1,&H03,&H00
65285 DATA &H2E,&H8B,&H1E,&H05,&H00
65290 DATA &H2E,&H8B,&H0E,&H07,&H00
65295 DATA &H2E,&H8B,&H16,&H09,&H00
65300 DATA &H1E,&H07
65305 DATA &HCD,&H21                                     :REM INTERRUPT% XX
65310 DATA &H2E,&HA3,&H03,&H00
65315 DATA &H2E,&H89,&H1E,&H5,&H0
65320 DATA &H2E,&H89,&H0E,&H07,&H00
65325 DATA &H2E,&H89,&H16,&H09,&H00
65330 DATA &HCB                                          :REM RETF
